/*********************************************************

 UDP abstract protocol.

 CopyRight (C) 2009 Evgeny Nekrasov

*********************************************************/
#ifdef __WIN32__
#include <winsock2.h>
#else
#include <sys/socket.h>
#endif

#include "n1d_buffer.h"
#include "n1d_types.h"

#define UAP_HND 1  // handshake
#define UAP_LSS 2  // list servers
#define UAP_MKG 3  // make game
#define UAP_LSG 4  // list games
#define UAP_JNG 5  // join to game
#define UAP_TRN 6  // my turn
#define UAP_GTN 7  // wait turn
#define UAP_EOG 8  // end of game
#define UAP_SET 9  // set value
#define UAP_PNG 10 // ping

// RET - ROK|RER
#define UAP_ROK 0 // return OK
#define UAP_RER 1 // return ERROR

#define UAP_ERROR_MAX_USERS_COUNT_REACHED  1000

// TUT - TUY|TUE
#define UAP_TUY 1 // turn is yours
#define UAP_TUE 0 // your enemy's turn

// WNR - WNI|WNE
#define UAP_WNI 1 // I am winner 
#define UAP_WNE 0 // Enemy won

#define UAP_PID 0x5044314E
#define UAP_HID_SIZE  16


/*************************************************************************************

PID - protocol id
HID - hardware id
GID - game id
SID - session id (number of current user in array :)

Client                     Server

   -- PID,HND,HID,USER,PWD -->       1) HANDSHAKE
   <-- PID,RET,[SID|error] ---          return user SID (SID released 
                                        after some time)

   -- PID,SET,SID,id,value -->       A) SET VARIABLE
   <-------- PID,RET ---------          sets variable number "id" to "value"

   ------ PID,PNG,SID ------->       B) PING SERVER
   <-------- PID,RET ---------          

   ------- PID,LSS,SID ------>       2) LIST SERVERS
   <---- PID,srv1,srv2,0 -----          returns game servers

   -- PID,LSS,SID,GID,name -->       3) CREATE GAME
   <-- PID,RET[,sid|error] ---          if ROK returns enemy SID else
                                        error message

   ---- PID,LSG,SID,GID ----->       4) LIST GAMES (user can do it many times)
   <-- PID,RET,name1,sid,0 ---          if ROK returns games names and SIDs

   ---- PID,JNG,SID,sid ----->       5) JOIN TO GAME
   <-- PID,RET[,TUT|error] ---          returns turn state or error message

   ---- PID,TRN,SID,data1 --->       6) MY TURN
   <----- PID,RET,data2 ------          return enemy data

   ------- PID,GTN,SID ------>       7) WAIT ENEMY TURN
   <---- PID,RET[,data] ------          return enemy turn

   ----- PID,OEG,SID,WNR ---->       8) END OF GAME
   <--------- PID,RET --------          RER returns if result not 
                                        corresponding with enemy

*************************************************************************************/


void uap_initialize()
{
    n1d_sessions_initialize();
}


void onHandshake(UserHardwareIdType hid, const char *name, const char* pwd)
{
    if (1) //check user
    {
        int sid = findFreeSession();
        if(sid==-1)
        {
            //return error;
            addNum(ptr, UAP_PID);
            addNum(ptr, UAP_RER);
            addNum(ptr, UAP_ERROR_MAX_USERS_COUNT_REACHED);
        }
    }

}

int onReceiveData(const void* data, int size)
{
    const char* ptr = (const char*)data;
    const char* end = ptr + size;

    uint32 pid = getNum(ptr);
    if(pid != UAP_PID) return 0;

    uint32 action = getNum(ptr);
    switch(action)
    {
        case UAP_HND:
        {
            const char * hid  = getHID(ptr);
            const char * name = getStr(ptr);
            const char * pwd  = getStr(ptr);
            if(ptr!=end) return 0;
            onHandshake(hid, name, pwd);
            break;
        }
        case UAP_LSS:
        case UAP_MKG:
        case UAP_LSG:
        case UAP_JNG:
        case UAP_TRN:
        case UAP_GTN:
        case UAP_EOG:
        default: return 0;
    }

    return 0;
}
